package com.omt.tarjimdinek.conversation;

import static com.omt.tarjimdinek.conversation.ConversationHolder.getCurrentConversation;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;

import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.omt.tarjimdinek.context.LogContext;
import com.omt.tarjimdinek.context.UserContext;
import com.omt.tarjimdinek.util.UserContextUtil;

/**
 * Filter responsible for creating/resuming {@link Conversation}.
 * By convention, the conversation id is carried by the _cid_ parameter.
 * To create a new conversation, you must request the initial conversation view and pass the _ncid_=value parameter.
 */
@Named
public class ConversationFilter implements Filter {
    private static final Logger log = Logger.getLogger(ConversationFilter.class);

    @Inject
    private ConversationManager conversationManager;

	private HashSet<String> listAnonymousPage = new HashSet<String>(Arrays.asList("/home.faces", "/getPassword/index.faces", 
			"/accountValidate/index.faces"));

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // set up log context for this thread so these information can be used by log4j
        String username = UserContext.getUsername();
        LogContext.setLogin(username != null ? username : "no username");
        LogContext.setSessionId(request.getSession().getId());

        String cid = request.getParameter("_cid_");

        if (cid != null) {
            // -----------------------------
            // RESUME existing conversation
            // -----------------------------
            try {
                conversationManager.resumeConversation(cid, request);
                if (log.isDebugEnabled()) {
                    log.debug("Conv. " + cid + " resumed. Nb ctx: " + getCurrentConversation().getConversationContextesCount() + ". Uri: "
                            + request.getRequestURI());
                }
            } catch (UnexpectedConversationException uue) {
                log.error(uue.getMessage());
                response.sendRedirect(request.getContextPath() + uue.getRedirectUrl());
                return;
            }

            try {
                filterChain.doFilter(request, response);
            } finally {
                conversationManager.pauseCurrentConversation();
            }
        } else if (!request.getRequestURI().contains("/javax.faces.resource/") && "true".equals(request.getParameter("_ncid_"))) {
            // -----------------------------
            // CREATE new conversation
            // -----------------------------

            // Limitation (per user) on the number of simultaneous conversations.
            if (conversationManager.isMaxConversationsReached(request.getSession())) {
                response.sendRedirect(request.getContextPath() + "/error/limit.faces");
                return;
            } else {
                // CREATE a new conversation
                try {
                    Conversation conversation = conversationManager.createConversation(request);
                    response.sendRedirect(request.getContextPath() + conversation.nextUrl());
                } catch (UnexpectedConversationException uue) {
                    log.error(uue.getMessage());
                    response.sendRedirect(request.getContextPath() + uue.getRedirectUrl());
                }
                return;
            }
        } else {
        	// if user is loggin then redirect him to his account
            if (!UserContext.ANONYMOUS_USER.equalsIgnoreCase(UserContext.getUsername()) && 
    	        		(listAnonymousPage.contains(request.getServletPath()) ||
    	    			isListAnonymousPageStartWith(request.getServletPath()))
        			) {
    	    	try {
    				response.sendRedirect(request.getContextPath() + "/member/home.faces");
    			} catch (IOException uue) {
    				log.error(uue.getMessage());
    			}
        	} else {
	            // -----------------------------
	            // Not related to conversations
	            // -----------------------------
	           filterChain.doFilter(request, response);
        	}
        }
        
        
    }

    /**
     * Check if servlet path start with list anonymous values
     * @param servletPath
     * @return
     */
    private boolean isListAnonymousPageStartWith(String aServletPath) {
    	for(String lPage : listAnonymousPage){
    		if(lPage.toUpperCase().startsWith(aServletPath.toUpperCase()) ||
    				lPage.toUpperCase().contains(aServletPath.toUpperCase())){
    			return true;
    		}
    	}
		return false;
	}

	@Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}